import json
import random
import re

from functools import wraps

from django.http.response import JsonResponse

from django_redis import get_redis_connection
from rest_framework.response import Response
from rest_framework.views import APIView

from apps.news.models import Channel, UserChannel, Article, Attitude, Collection, ArticleContent, Read, Comment
from apps.demo.models import User, Relation
from utils.Audit_comment import Audit
from utils.caches import custom_cache_decorator, public_cache_decorator
# from utils.caches import custom_cache_decorator
from utils.jwt000 import generate_refresh_token, generate_access_token, decode_jwt
from django.utils.decorators import method_decorator

# Create your views here.


class SendView(APIView):
    def get(self, request, mobile):
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return {'code': 400, 'message': '参数mobile有误'}
        code = str((random.randint(1000, 9999)))
        # code = str(random.randint(10000,99999))   #这是生成6位的验证码
        # 通过方法来进行发送短信
        # send_messages(mobile, code)
        # 在控制台中输出我们需要的验证码
        if code is not None and mobile is not None:
            redis_client = get_redis_connection('code')
            redis_client.setex(mobile, 120, code)
        else:
            print("Code or mobile is None")
        print(code)
        # 把验证码存入我们的redis当中
        # redis_cli.setex(mobile, 120,code)
        # 进行返回给前端数据
        try:
            redis_client = get_redis_connection('code')
            redis_client.setex(mobile, 120, code)
        except Exception as e:
            print("An error occurred:", e)
            print("Code:", code)
            print("Mobile:", mobile)
        return JsonResponse({'message': 'ok', 'data': {'mobile': mobile}})


class LoginView(APIView):
    def post(self, request):
        data = request.data
        mobile = data.get('mobile')
        code = data.get('code')
        redis_code = get_redis_connection('code').get(mobile)
        if redis_code is None:
            return JsonResponse({'code': 400, 'errmsg': '验证码错误'}, status=400)
        if redis_code.decode() != code:
            return JsonResponse({'code': 400, 'errmsg': '密码错误'}, status=400)
        users = User.objects.filter(mobile=mobile)
        if not users:
            user = User.objects.create(nickname=mobile, mobile=mobile)
            user.save()
        else:
            user = User.objects.filter(mobile=mobile)

        token = generate_access_token({'user_id': user.first().id, 'mobile': user.first().mobile}).decode()
        refresh_token = generate_refresh_token({'user_id': user.first().id, 'mobile': user.first().mobile}).decode()
        res = JsonResponse({"message": "ok", "data": {"token": token, "refresh_token": refresh_token}})
        res.set_cookie('user_id',user.first().id,expires=24*60*60)
        return res


    def put(self, request):
        try:
            token = request.META.get('HTTP_AUTHORIZATION')[7:]
            data = decode_jwt(token)
            user_id = data.get('user_id')
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '用户未登录'})
        try:
            user = User.objects.get(pk=user_id)
        except:
            return JsonResponse({'code': 0, 'errmsg': 'ok'})
        token = generate_refresh_token({'user_id': user.id, 'mobile': user.mobile}).decode()
        res= JsonResponse({"message": "OK", "data": {"token": token, }})
        res.set_cookie('user_id',user.id,expires=24*60*60)
        return res


class UserinfoView(APIView):
    def get(self, request):
        try:
            token = request.META.get('HTTP_AUTHORIZATION')[7:]
            data = decode_jwt(token)
            user_id = data.get('user_id')
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '用户未登录'})
        # 使用user_id作为缓存键
        redis_conn = get_redis_connection()
        user_data = redis_conn.get('user_info')
        if user_data is not None:
            # 如果缓存中有数据，则直接返回
            return JsonResponse(json.loads(user_data))
        following_count = Relation.objects.filter(user_id=user_id).count()  # 查询关注数
        fans_count = Relation.objects.filter(target_user_id=user_id).count()  # 查询粉丝数
        art_count = Article.objects.filter(user_id=user_id).count()  # 查询文章数
        user = User.objects.get(id=user_id)
        user_data = {
            "message": "OK",
            "data": {
                "id": user_id,
                "name": user.nickname,
                "photo": user.profile_photo,
                "intro": user.introduction,
                "art_count": art_count,
                "follow_count": following_count,
                "fans_count": fans_count
            }
        }
        # 将用户数据保存到缓存中，并设置过期时间为60秒
        redis_conn.set('user_info_%s' % user_id, json.dumps(user_data), ex=2 * 60 * 60)
        return JsonResponse(user_data)


class ChannelView(APIView):
    def get(self, request):
        redis_conn = get_redis_connection()
        list1 = redis_conn.get('channels')
        if not list1:
            data = Channel.objects.all()
            list1 = []
            for i in data:
                list1.append({
                    'id': i.id,
                    'name': i.name
                })
            redis_conn.set('channels', json.dumps({"message": "OK", "data": {"channels": list1}}), ex=2 * 60 * 60)
            return JsonResponse({"message": "OK", "data": {"channels": list1}})
        list1 = json.loads(list1)
        return JsonResponse(list1)


class UserChannelView(APIView):

    def get(self, request):
        try:
            token = request.META.get('HTTP_AUTHORIZATION')[7:]
            data = decode_jwt(token)
            user_id = data.get('user_id')
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '用户未登录'})
        redis_conn = get_redis_connection()
        data_list = redis_conn.get('channel_%ss')
        if not data_list:
            ChannllID = UserChannel.objects.filter(user_id=user_id)  # 获取用户的频道ID列表
            data_list = []
            for i in ChannllID:  # 遍历频道ID列表
                data_list.append({  # 将频道信息添加到数据列表中
                    'id': i.channel.id,  # 频道ID
                    'name': i.channel.name  # 频道名称
                })
            redis_conn.set('channel_%ss', json.dumps({"message": "OK", "data": {"channels": data_list}}), ex=3600)
            return JsonResponse({"message": "OK", "data": {"channels": data_list}})  # 返回消息和频道信息
        data_list = json.loads(data_list)
        return JsonResponse(data_list)

    def put(self, request):
        token = request.META.get('HTTP_AUTHORIZATION')[7:]
        data1 = decode_jwt(token)
        data = request.data
        channels = data.get('channels')
        user_id = data1.get('user_id')
        UserChannel.objects.filter(user_id=user_id).delete()
        for channel in channels:
            obj = UserChannel.objects.create(user_id=user_id, channel_id=channel.get('id'), sequence=channel.get('seq'))
            obj.save()
        userchannl = UserChannel.objects.filter(user_id=user_id)
        channe = []
        for i in userchannl:
            channe.append({
                'id': i.channel.id,
                'name': i.channel.name
            })
        redis_conn =get_redis_connection()
        redis_conn.set('channel_idid', json.dumps(channe),ex=3600)
        return JsonResponse({"errmsg": "OK", "data": {"channels": channe}})


class ArticleView(APIView):
    @method_decorator(public_cache_decorator())
    def get(self, reqeust):
        channel_id = reqeust.GET.get('channel_id')
        channles = Article.objects.filter(channel_id=channel_id)
        obj = []
        for i in channles:
            obj.append({
                'art_id': i.id,  # 文章ID
                'title': i.title,  # 文章标题
                'aut_id': i.user.id,  # 作者ID
                'pubdate': str(i.create_time),  # 发布日期
                'aut_name': i.user.nickname,  # 作者名字
                'comm_count': i.comment_count,  # 评论数
                'is_top': 0,  # 是否置顶
            })
        return JsonResponse({'message': 'ok', 'data': {'pre_timestamp': 2, 'results': obj}})






class DetailView(APIView):
    def get(self, request, article_id):
        try:
            token = request.META.get('HTTP_AUTHORIZATION')[7:]
            data = decode_jwt(token)
            user_id = data.get('user_id')
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '用户未登录'})
        mobile = data.get(('mobile'))
        user = User.objects.get(id=user_id, mobile=mobile)
        i = Article.objects.get(id=article_id)
        cooo = ArticleContent.objects.get(article_id=article_id)
        redis_conn = get_redis_connection()
        # 获取缓存中的数据
        is_followed = redis_conn.get('is_followed_cache_%s_%s' % (article_id, user_id))
        attitude = redis_conn.get('attitude_cache_%s_%s' % (article_id, user_id))
        is_collected = redis_conn .get('is_collected_cache_%s_%s' % (article_id, user_id))
        essay_cached_data = redis_conn.get('essay_cached_data_%s' % article_id)
        # 将需要缓存的数据存储到缓存中
        if is_collected is None:
            is_collected = Collection.objects.filter(user_id=user_id, article=i)
            is_collected = json.dumps(True if is_collected else False)
            redis_conn.set('is_collected_cache_%s_%s' % (article_id, user_id), is_collected, ex=24 * 60 * 60)
        if attitude is None:
            attitude = Attitude.objects.filter(user_id=user_id, article=i)
            attitude = json.dumps(attitude.first().attitude if attitude else -1)
            redis_conn.set('attitude_cache_%s_%s' % (article_id, user_id), attitude, ex=24 * 60 * 60)
        if is_followed is None:
            is_followed = Relation.objects.filter(user_id=user_id, target_user_id=i.user.id)
            is_followed = json.dumps(True if is_followed else False)
            redis_conn.set('is_followed_cache_%s_%s' % (article_id, user_id), is_followed, ex=24 * 60 * 60)
        if essay_cached_data is  None:
            essay_cached_data = {
                "art_id": i.id,
                "title": i.title,
                "pubdate": str(i.create_time),
                "aut_id": i.user.id,
                "aut_name": i.user.nickname,
                'aut_photo': i.user.profile_photo,
                "content": cooo.content,
            }
            essay_cached_data = json.dumps(essay_cached_data)
            redis_conn.set('essay_cached_data_%s'%  article_id,essay_cached_data,ex=2*60*60)

            aa = Read.objects.filter(user_id=user_id, article_id=article_id)
            if not aa:
                aa = Read.objects.create(user_id=user_id, article_id=article_id)
                aa.save()

        return JsonResponse({"message": "ok",
                                 "data": {
                                     **json.loads(essay_cached_data),
                                     'is_followed':json.loads(is_followed),
                                     'attitude':json.loads(attitude),
                                     'is_collected':json.loads(is_collected)
                                 }})


class FollowedView(APIView):
    def post(self, request):
        try:
            token = request.META.get('HTTP_AUTHORIZATION')[7:]
            data = decode_jwt(token)
            user_id = data.get('user_id')
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '用户未登录'})
        target = request.data.get('target')
        rr = Relation.objects.filter(user_id=user_id, target_user_id=target)
        if not rr:
            pp = Relation.objects.create(user_id=user_id, target_user_id=target, relation=2)
            pp.save()
        return JsonResponse({"message": "OK", "data": {"target": target}})
    @method_decorator(custom_cache_decorator())
    def get(self, request):
        try:
            token = request.META.get('HTTP_AUTHORIZATION')[7:]
            data = decode_jwt(token)
            user_id = data.get('user_id')
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '用户未登录'})
        aaaa = Relation.objects.filter(user_id=user_id)  # 所有数据
        # 用户表
        results = []
        for i in aaaa:
            user1 = User.objects.get(id=user_id)
            fans_count = Relation.objects.filter(target_user_id=i.target_user_id).count()  # 我关注的人数
            target_user = Relation.objects.filter(target_user_id=i.target_user_id)  # 获取 关注的对象
            follow = Relation.objects.filter(user_id=target_user.first().target_user_id, target_user_id=user_id)
            results.append({
                "id": user1.id,
                "name": user1.nickname,
                "photo": user1.profile_photo,
                "fans_count": fans_count,  # 粉丝数量
                "mutual_follow": True if follow else False  # 是否为互相关注
            })
        return JsonResponse({"message": "OK", "data": {"total_count": len(results), "page": 2, "per_page": 2, "results": results}})


class UFollowedView(APIView):

    def delete(self, request, id):
        try:
            token = request.META.get('HTTP_AUTHORIZATION')[7:]
            data = decode_jwt(token)
            user_id = data.get('user_id')
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '用户未登录'})
        target = id
        aa = Relation.objects.filter(user_id=user_id, target_user_id=target)
        aa.delete()
        return JsonResponse({'message': 'ok'})


class LikeingView(APIView):

    def post(self, request):
        try:
            token = request.META.get('HTTP_AUTHORIZATION')[7:]
            data = decode_jwt(token)
            user_id = data.get('user_id')
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '用户未登录'})
        target = request.data.get('target')
        aa = Attitude.objects.filter(user_id=user_id, article_id=target)
        if not aa:
            attit = Attitude.objects.create(user_id=user_id, article_id=target, attitude=1)
            attit.save()
        return JsonResponse({"message": "OK", "data": {"target": target}})


class ULikeingView(APIView):

    def delete(self, request, id):
        try:
            token = request.META.get('HTTP_AUTHORIZATION')[7:]
            data = decode_jwt(token)
            user_id = data.get('user_id')
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '用户未登录'})
        target = id
        aa = Attitude.objects.filter(user_id=user_id, article_id=target)
        aa.delete()
        return JsonResponse({'message': 'ok'})


class UDisliskeingView(APIView):

    def post(self, request):
        try:
            token = request.META.get('HTTP_AUTHORIZATION')[7:]
            data = decode_jwt(token)
            user_id = data.get('user_id')
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '用户未登录'})
        target = request.data.get('target')
        oo = Attitude.objects.filter(user_id=user_id, article_id=target)
        if not oo:
            attit = Attitude.objects.create(user_id=user_id, article_id=target, attitude=0)
            attit.save()
        return JsonResponse({"message": "OK", "data": {"target": target}})

    def delete(self, request, id):
        try:
            token = request.META.get('HTTP_AUTHORIZATION')[7:]
            data = decode_jwt(token)
            user_id = data.get('user_id')
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '用户未登录'})
        target = id
        aa = Attitude.objects.filter(user_id=user_id, article_id=target)
        aa.delete()
        return JsonResponse({'message': 'ok'})


class CollectView(APIView):

    def post(self, request):
        try:
            token = request.META.get('HTTP_AUTHORIZATION')[7:]
            data = decode_jwt(token)
            user_id = data.get('user_id')
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '用户未登录'})
        target = request.data.get('target')
        try:
            Collection.objects.get(user_id=user_id, article_id=target).delete()
        except Collection.DoesNotExist:
            Collection.objects.create(user_id=user_id, article_id=target)
        redis_conn = get_redis_connection()
        redis_conn.set('collect_%s' % user_id,target,ex=2*60*60)
        return JsonResponse({"message": "OK", "data": {"target": target}})
    # @custom_cache_decorator(custom_cache_decorator(timeout=2*60*60))
    def get(self, request):
        try:
            token = request.META.get('HTTP_AUTHORIZATION')[7:]
            data = decode_jwt(token)
            user_id = data.get('user_id')
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '用户未登录'})
        user = User.objects.get(id=user_id)
        collection_records = Collection.objects.filter(user_id=user_id).all()
        # 用于存储article_id的列表
        article_id_list = [i.article_id for i in collection_records]
        # 用于存储Article对象的列表
        article_list = []
        for article_id in article_id_list:
            # 查询文章对象
            article_obj = Article.objects.get(id=article_id)
            article_list.append(article_obj)
        # 用于存储结果列表
        result_list = []
        for article in article_list:
            # 查询用户对文章的态度记录
            attitude_record = Attitude.objects.filter(user_id=user_id, article_id=article.id)
            if attitude_record and attitude_record.attitude == 1:
                like = True
            else:
                like = False
            # 构建结果列表
            result_list.append({
                "art_id": article.id,
                "title": article.title,
                "aut_id": article.user.id,
                "aut_name": user.nickname,
                "aut_photo": article.user.profile_photo,
                "pubdate": str(article.create_time),
                'cover': article.cover,
                "images": [],
                "is_liking": like
            })
                # 存储结果到Redis
        redis_conn = get_redis_connection('cache')
        redis_key = 'user:{}:result_list'.format(user_id)  # 设置Redis键名
        redis_conn.set(redis_key, json.dumps(result_list),ex=7200)  # 将结果列表转换为字符串并存入Redis

        # 从Redis中获取数据
        data_str = redis_conn.get(redis_key)
        if data_str:
            data = json.loads(data_str)  # 解码为Python对象
            print(data)
        else:
            print('数据不存在')
        # 返回结果

        return JsonResponse({"message": "OK", "data": {"total_count": len(result_list), "results": result_list}})


class CommentView(APIView):
    def post(self, request):
        try:
            token = request.META.get('HTTP_AUTHORIZATION')[7:]
            data = decode_jwt(token)
            user_id = data.get('user_id')
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '用户未登录'})
        content = request.data.get('content')
        target = request.data.get('target')
        article_id = request.data.get('article_id')
        # 在这里进行调用函数
        res = Audit(content)
        # 进行判断   所评论内容是否违反审核标准
        # 获取参数进行判断
        if res.get('conclusion') != '合规':
            return {'code': 400}, 400
        try:
            parent_id = request.data.get('parent_id')
            comment = Comment.objects.create(user_id=user_id, article_id=target, content=content, parent_id=parent_id)
            comment.save()
        except:
            comment = Comment.objects.create(user_id=user_id, article_id=target, content=content, parent_id=article_id)
            comment.save()
        return JsonResponse({"message": "OK", "data": {"com_id": comment.content, "target": target}})

    def get(self, request):
        try:
            token = request.META.get('HTTP_AUTHORIZATION')[7:]
            data = decode_jwt(token)
            user_id = data.get('user_id')
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '用户未登录'})
        type = request.GET.get('type')
        source = request.GET.get('source')
        offset = request.GET.get('offset', None)
        limit = request.GET.get('limit', None)
        if type == 'a':
            parent_id = request.data.get('parent_id')
            cc = Comment.objects.filter(user_id=user_id,article_id=source, parent_id=None)
            # end_id =Comment.objects.filter(user_id=user_id,article=source,parent_id=target).last().id
        else:
            cc = Comment.objects.filter(user_id=user_id,parent_id=source)
            # last_id =Comment.objects.filter(user_id=user_id,article_id=source).last().id
        comment_list = []
        for i in cc:
            comment_list.append({
                "com_id": i.id,
                "aut_id": i.user.id,
                "aut_name": i.user.nickname,
                "aut_photo": i.user.profile_photo,
                "pubdate": str(i.create_time),
                "content": i.content,
                "is_top": i.is_top,
                "is_liking": 0
            })
        return JsonResponse({'message': 'ok', 'data': {'total_count': len(comment_list), 'end_id': 108, 'last_id': 108,'results': comment_list}})


class HistoryView(APIView):
    def get(self, request):
        try:
            token = request.META.get('HTTP_AUTHORIZATION')[7:]
            data = decode_jwt(token)
            user_id = data.get('user_id')
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '用户未登录'})
        redis_conn = get_redis_connection()
        # obj =redis_conn.zrange('history_%s', 0, -1)


        data = Read.objects.all()  # 从数据库中读取所有阅读数据
        list1 = []
        for i in data:
             pppp = Article.objects.get(id=i.article_id)  # 文章基本信息表
             list1.append({
                 "art_id": user_id,
                 "title": pppp.title,  # 标题
                 "aut_id": pppp.user.id,  # 评论或回复用户id
                 "aut_name": pppp.user.nickname,  # 用户昵称
                 "aut_photo": pppp.user.profile_photo,  # 用户头像
                 "pubdate": str(i.create_time),  # 创建时间
             })
        redis_conn = get_redis_connection('cache')
        redis_key = 'user:{}:history'.format(user_id)  # 设置Redis键名
        redis_conn.set(redis_key, json.dumps(list1),ex=7200)  # 将结果列表转换为字符串并存入Redis

        # 从Redis中获取数据
        data_str = redis_conn.get(redis_key)
        if data_str:
            data = json.loads(data_str)  # 解码为Python对象
            print(data)
        else:
            print('数据不存在')
        # 返回结果
        # aaa= []
        # for i in obj:
        #     aaa.append(i.decode())
        return JsonResponse({"message": "OK", "data": {"total_count": len(list1), "results": list1}})






class FollowView(APIView):
    @method_decorator(custom_cache_decorator())
    def get(self, request):
        try:
            token = request.META.get('HTTP_AUTHORIZATION')[7:]
            data = decode_jwt(token)
            user_id = data.get('user_id')
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '用户未登录'})
        userRelationships = Relation.objects.filter(target_user_id=user_id)  # 所有数据
        results = []
        for i in userRelationships:
            user1 = User.objects.get(id=i.target_user_id)  # 用户表
            mutual_follow = Relation.objects.filter(target_user_id=i.user_id, relation=1,user_id=user_id)  # 查询id是否为粉丝的,关注的id为我
            results.append({
                "id": user1.id,
                "name": user1.nickname,
                "photo": user1.profile_photo,
                "fans_count": 1,  # 粉丝数量
                "mutual_follow": False if mutual_follow is None else True  # 是否为互相关注
            })
        return JsonResponse({"message": "OK", "data": {"total_count": len(results), "page": 6, "per_page": 6, "results": results}})
